package com.th.cash.th2.product;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import com.th.resmodel.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatAutoCompleteTextView;

public class EmailAutoCompleteTextView extends AppCompatAutoCompleteTextView {

    private String[] address = new String[]{"@gmail.com", "@yahoo.com", "@icloud.com", "@outlook.com"};

    public EmailAutoCompleteTextView(Context context) {
        super(context);
        initViews();
    }

    public EmailAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initViews();
    }

    public EmailAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews();
    }

    private void initViews() {
        setAdapter(new EmailAdapter(new ArrayList<String>(Arrays.asList(address))));
        setThreshold(1);    //使得在输入1个字符之后便弹出pop
    }


    @Override
    protected void onFocusChanged(boolean hasFocus, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(hasFocus, direction, previouslyFocusedRect);
        if (hasFocus) {
            String text = EmailAutoCompleteTextView.this.getText().toString();
            if (!"".equals(text))
                performFiltering(text, 0);
        }
    }

    @Override
    protected void replaceText(CharSequence text) {
        String t = this.getText().toString();
        //当我们在下拉框中选择一项时，android会默认使用AutoCompleteTextView中Adapter里的文本来填充文本域
        //因为这里Adapter中只是存了常用email的后缀
        //因此要重新replace逻辑，将用户输入的部分与后缀合并
        int index = t.indexOf("@");
        if (index != -1)
            t = t.substring(0, index);
        super.replaceText(t + text);

    }

    @Override
    protected void performFiltering(CharSequence text, int keyCode) {
        //该方法会在用户输入文本之后调用，将已输入的文本与adapter中的数据对比，若它匹配
        //adapter中数据的前半部分，那么adapter中的这条数据将会在下拉框中出现
        String t = text.toString();
        //因为用户输入邮箱时，都是以字母，数字开始，而我们的adapter中只会提供以类似于"@163.com"
        //的邮箱后缀，因此在调用super.performFiltering时，传入的一定是以"@"开头的字符串
        int index = t.indexOf("@");
        if (index == -1) {
            if (t.matches("^[a-zA-Z0-9_]+$")) {
                super.performFiltering("@", keyCode);
            } else
                this.dismissDropDown();//当用户中途输入非法字符时，关闭下拉提示框
        } else {
            super.performFiltering(t.substring(index), keyCode);
        }
    }


    class EmailAdapter extends ArrayAdapter<String> {

        public EmailAdapter(@NonNull List<String> objects) {
            super(EmailAutoCompleteTextView.this.getContext(), R.layout.item_email_auto_complete, R.id.textView, objects);
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            View v = convertView;
            if (v == null)
                v = LayoutInflater.from(getContext()).inflate(
                        R.layout.item_email_auto_complete, null);
            String originStr = EmailAutoCompleteTextView.this.getText().toString();
            int index = originStr.indexOf("@");
            if (index != -1)
                originStr = originStr.substring(0, index);
            final TextView textView = (TextView) v.findViewById(R.id.textView);
            textView.setText(originStr + getItem(position));
            return textView;
        }

        @NonNull
        @Override
        public Filter getFilter() {
            return new ArrayFilter();
        }

        /**
         * 修改ArrayAdapter源码 中的ArrayFilter，以改变其过滤规则
         * 默认过滤规则为 startWith == true
         * 修改后的规则： contains == true
         */
        private class ArrayFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                final FilterResults results = new FilterResults();
                if (prefix == null || prefix.length() == 0) {
                    final List<String> list;
                    synchronized (this) {
                        list = Arrays.asList(address.clone());
                    }
                    results.values = list;
                    results.count = list.size();
                } else {
                    String prefixString = prefix.toString().toLowerCase();
                    prefixString = prefixString.substring(1);
                    final ArrayList<String> values;
                    synchronized (this) {
                        values = new ArrayList<>(Arrays.asList(address));
                    }
                    final int count = values.size();
                    final ArrayList<String> newValues = new ArrayList<>();

                    for (int i = 0; i < count; i++) {
                        final String value = values.get(i);
                        final String valueText = value.toString().toLowerCase();
                        // First match against the whole, non-splitted value
                        if (valueText.contains(prefixString)) {
                            newValues.add(value);
                        } else {
                            final String[] words = valueText.split(" ");
                            for (String word : words) {
                                if (word.contains(prefixString)) {
                                    newValues.add(value);
                                    break;
                                }
                            }
                        }
                    }

                    results.values = newValues;
                    results.count = newValues.size();
                }

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                //noinspection unchecked
                clear();
                if (results.count > 0) {
                    for (String str : (List<String>) results.values) {
                        add(str);
                    }
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        }

    }
}